package com.shrct.businessprocess.product.impl;

import com.google.common.base.Objects;
import com.shrct.businessprocess.budget.RCBudget;
import com.shrct.businessprocess.budget.RCCostBreakDown;
import com.shrct.businessprocess.organization.RCEnterprise;
import com.shrct.businessprocess.organization.RCOrganizationService;
import com.shrct.businessprocess.organization.RCSupplier;
import com.shrct.businessprocess.product.RCCompanyServiceEntry;
import com.shrct.businessprocess.product.RCIdentifiablePhysicalProductEntry;
import com.shrct.businessprocess.product.RCIdentifiablePhysicalProductEntryDAO;
import com.shrct.businessprocess.product.RCIdentifiablePhysicalProductPurchaseInfo;
import com.shrct.businessprocess.product.RCLogicProduct;
import com.shrct.businessprocess.product.RCLogicProductDAO;
import com.shrct.businessprocess.product.RCNormalizerService;
import com.shrct.businessprocess.product.RCProductServiceTracer;
import com.shrct.businessprocess.product.RCProductSpecification;
import com.shrct.businessprocess.product.RCRegisterIdentifiablePhysicalPruductEvent;
import com.shrct.businessprocess.product.RCServiceInfo;
import com.shrct.businessprocess.product.RCUnregisterIdentifiablePhysicalPruductEvent;
import com.shrct.businessprocess.product.impl.RCIdentifiablePhysicalProductEntryImpl;
import com.shrct.businessprocess.product.impl.RCProductServiceTracerImpl;
import com.shrct.businessprocess.product.impl.RCRegisterIdentifiablePhysicalPruductEventImpl;
import com.shrct.businessprocess.product.impl.RCUnregisterIdentifiablePhysicalPruductEventImpl;
import com.shrct.businessprocess.project.RCParameterService;
import com.shrct.businessprocess.project.RCProject;
import com.shrct.businessprocess.purchase.RCBudgetContract;
import com.shrct.businessprocess.purchase.RCBudgetContractProductItem;
import com.shrct.businessprocess.purchase.RCContractItemPromisedService;
import com.shrct.businessprocess.purchase.RCIdentifiablePhysicalProductInStockEvent;
import com.shrct.businessprocess.purchase.RCIdentifiableProductInStockEvent;
import com.shrct.businessprocess.purchase.RCPurchaseOrder;
import com.shrct.businessprocess.purchase.RCPurchaseOrderItem;
import com.shrct.businessprocess.purchase.impl.RCIdentifiablePhysicalProductInStockEventImpl;
import com.uniquesoft.uidl.validation.Validates;
import edu.fudan.langlab.domain.security.ISystemUserService;
import edu.fudan.langlab.domain.security.User;
import edu.fudan.mylang.pf.BaseDAOService;
import edu.fudan.mylang.pf.IGenericQuery;
import edu.fudan.mylang.utils.DateUtil;
import java.util.Collection;
import java.util.Date;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("com.shrct.businessprocess.product.RCIdentifiablePhysicalProductEntryDAO")
public class RCIdentifiablePhysicalProductEntryDAOImpl extends BaseDAOService<RCIdentifiablePhysicalProductEntry> implements RCIdentifiablePhysicalProductEntryDAO {
  @Autowired
  private ISystemUserService systemUserService;
  
  @Autowired
  private RCOrganizationService organizationService;
  
  @Autowired
  private RCParameterService parameterService;
  
  @Autowired
  private RCNormalizerService normalizerService;
  
  @Autowired
  private RCLogicProductDAO logicProductDAO;
  
  public RCIdentifiablePhysicalProductEntry create(final String _sid, final Procedure1<? super RCIdentifiablePhysicalProductEntry> postInit) {
    RCIdentifiablePhysicalProductEntry _xblockexpression = null;
    {
      final String normalizedSid = _sid.toUpperCase();
      String _xifexpression = null;
      boolean _notEquals = (!Objects.equal(normalizedSid, "-"));
      if (_notEquals) {
        String _xblockexpression_1 = null;
        {
          Boolean _isSidUnique = this.isSidUnique(normalizedSid);
          String _plus = ("\u4EA7\u54C1\u5E8F\u5217\u53F7\u5DF2\u5B58\u5728:" + _sid);
          Validates.Assert((_isSidUnique).booleanValue(), _plus);
          _xblockexpression_1 = (normalizedSid);
        }
        _xifexpression = _xblockexpression_1;
      } else {
        Integer _nextProductSid = this.parameterService.getNextProductSid();
        String _format = String.format("%08d", _nextProductSid);
        String _plus = ("RC_" + _format);
        _xifexpression = _plus;
      }
      final String sid = _xifexpression;RCIdentifiablePhysicalProductEntry rCIdentifiablePhysicalProductEntry=RCIdentifiablePhysicalProductEntryImpl.create(getObjectFactory());
      final Procedure1<RCIdentifiablePhysicalProductEntry> _function = new Procedure1<RCIdentifiablePhysicalProductEntry>() {
          public void apply(final RCIdentifiablePhysicalProductEntry it) {
            it.setSid(sid);
            String _normalizeSid = RCIdentifiablePhysicalProductEntryDAOImpl.this.normalizerService.normalizeSid(sid);
            it.setNormalizedSid(_normalizeSid);
            it.start();
            postInit.apply(it);
          }
        };
      RCIdentifiablePhysicalProductEntry _doubleArrow = ObjectExtensions.<RCIdentifiablePhysicalProductEntry>operator_doubleArrow(rCIdentifiablePhysicalProductEntry, _function);
      _xblockexpression = (_doubleArrow);
    }
    return _xblockexpression;
  }
  
  public Boolean isSidUnique(final String sid) {
    IGenericQuery<RCIdentifiablePhysicalProductEntry> query=getObjectFactory().createGenericQuery(RCIdentifiablePhysicalProductEntry.class,"select e from com.shrct.businessprocess.product.impl.RCIdentifiablePhysicalProductEntryImpl as e   where ((e.sid) = (:sid)) and  e.active = 1      ").setParameter("sid",sid);
    Collection<RCIdentifiablePhysicalProductEntry> _list = query.list();
    int _size = _list.size();
    boolean _equals = (_size == 0);
    return Boolean.valueOf(_equals);
  }
  
  /**
   * 产品登记。主要用于初始化数据的导入
   */
  public RCIdentifiablePhysicalProductEntry _registerPhysicalProduct(final String projectid, final RCEnterprise enterprise, final String _sid, final Integer count) {
    final Procedure1<RCIdentifiablePhysicalProductEntry> _function = new Procedure1<RCIdentifiablePhysicalProductEntry>() {
        public void apply(final RCIdentifiablePhysicalProductEntry physicalProduct) {
          final Procedure1<RCLogicProduct> _function = new Procedure1<RCLogicProduct>() {
              public void apply(final RCLogicProduct it) {
                it.setCurrentProduct(physicalProduct);
              }
            };
          RCLogicProduct _create = RCIdentifiablePhysicalProductEntryDAOImpl.this.logicProductDAO.create(projectid, _function);
          physicalProduct.setLogicProduct(_create);
          physicalProduct.setCount(count);
          physicalProduct.setProjectId(projectid);
          physicalProduct.setEnterprise(enterprise);
          RCLogicProduct _logicProduct = physicalProduct.getLogicProduct();RCRegisterIdentifiablePhysicalPruductEvent rCRegisterIdentifiablePhysicalPruductEvent=RCRegisterIdentifiablePhysicalPruductEventImpl.create(_logicProduct,enterprise,getObjectFactory());
          final Procedure1<RCRegisterIdentifiablePhysicalPruductEvent> _function_1 = new Procedure1<RCRegisterIdentifiablePhysicalPruductEvent>() {
              public void apply(final RCRegisterIdentifiablePhysicalPruductEvent it) {
                Date _day = DateUtil.today();
                it.setDate(_day);
                User _currentUser = RCIdentifiablePhysicalProductEntryDAOImpl.this.systemUserService.getCurrentUser();
                it.setOperator(_currentUser);
              }
            };
          ObjectExtensions.<RCRegisterIdentifiablePhysicalPruductEvent>operator_doubleArrow(rCRegisterIdentifiablePhysicalPruductEvent, _function_1);
        }
      };
    RCIdentifiablePhysicalProductEntry _create = this.create(_sid, _function);
    return _create;
  }
  
  public void transferPhysicalPruduct(final RCProject project, final RCIdentifiablePhysicalProductEntry product, final RCEnterprise enterprise, final Date serviceStartDate) {
    RCLogicProduct _logicProduct = product.getLogicProduct();
    RCEnterprise _enterprise = product.getEnterprise();RCUnregisterIdentifiablePhysicalPruductEvent rCUnregisterIdentifiablePhysicalPruductEvent=RCUnregisterIdentifiablePhysicalPruductEventImpl.create(_logicProduct,_enterprise,getObjectFactory());
    final Procedure1<RCUnregisterIdentifiablePhysicalPruductEvent> _function = new Procedure1<RCUnregisterIdentifiablePhysicalPruductEvent>() {
        public void apply(final RCUnregisterIdentifiablePhysicalPruductEvent it) {
          Date _day = DateUtil.today();
          it.setDate(_day);
          User _currentUser = RCIdentifiablePhysicalProductEntryDAOImpl.this.systemUserService.getCurrentUser();
          it.setOperator(_currentUser);
        }
      };
    ObjectExtensions.<RCUnregisterIdentifiablePhysicalPruductEvent>operator_doubleArrow(rCUnregisterIdentifiablePhysicalPruductEvent, _function);
    product.setEnterprise(enterprise);
    RCLogicProduct _logicProduct_1 = product.getLogicProduct();RCRegisterIdentifiablePhysicalPruductEvent rCRegisterIdentifiablePhysicalPruductEvent=RCRegisterIdentifiablePhysicalPruductEventImpl.create(_logicProduct_1,enterprise,getObjectFactory());
    final Procedure1<RCRegisterIdentifiablePhysicalPruductEvent> _function_1 = new Procedure1<RCRegisterIdentifiablePhysicalPruductEvent>() {
        public void apply(final RCRegisterIdentifiablePhysicalPruductEvent it) {
          Date _day = DateUtil.today();
          it.setDate(_day);
          User _currentUser = RCIdentifiablePhysicalProductEntryDAOImpl.this.systemUserService.getCurrentUser();
          it.setOperator(_currentUser);
        }
      };
    ObjectExtensions.<RCRegisterIdentifiablePhysicalPruductEvent>operator_doubleArrow(rCRegisterIdentifiablePhysicalPruductEvent, _function_1);
    IGenericQuery<RCIdentifiablePhysicalProductInStockEvent> query=getObjectFactory().createGenericQuery(RCIdentifiablePhysicalProductInStockEvent.class,"select e from com.shrct.businessprocess.purchase.impl.RCIdentifiablePhysicalProductInStockEventImpl as e   where ((e.product) = (:product)) and  e.active = 1      ").setParameter("product",product);
    RCIdentifiablePhysicalProductInStockEvent _uniqueResult = query.uniqueResult();
    final RCBudgetContractProductItem contractItem = _uniqueResult==null?(RCBudgetContractProductItem)null:_uniqueResult.getContractItem();
    boolean _notEquals = (!Objects.equal(contractItem, null));
    if (_notEquals) {
      Collection<RCContractItemPromisedService> _promisedServices = contractItem.getPromisedServices();
      final Procedure1<RCContractItemPromisedService> _function_2 = new Procedure1<RCContractItemPromisedService>() {
          public void apply(final RCContractItemPromisedService promisedItem) {
            RCServiceInfo _serviceInfo = promisedItem.getServiceInfo();
            Integer _monthes = _serviceInfo.getMonthes();
            final Date serviceEndDate = DateUtil.addMonths(serviceStartDate, (_monthes).intValue());
            RCLogicProduct _logicProduct = product.getLogicProduct();
            String _code = project.getCode();
            String _name = promisedItem.getName();
            RCServiceInfo _serviceInfo_1 = promisedItem.getServiceInfo();
            final RCCompanyServiceEntry companyService = _logicProduct.registerCompanyService(_code, _name, _serviceInfo_1, serviceStartDate, serviceEndDate);RCProductServiceTracer rCProductServiceTracer=RCProductServiceTracerImpl.create(getObjectFactory());
            final Procedure1<RCProductServiceTracer> _function = new Procedure1<RCProductServiceTracer>() {
                public void apply(final RCProductServiceTracer it) {
                  RCBudgetContract _contract = contractItem.getContract();
                  it.setBudgetContract(_contract);
                  it.setCompanyService(companyService);
                  it.setProduct(product);
                }
              };
            ObjectExtensions.<RCProductServiceTracer>operator_doubleArrow(rCProductServiceTracer, _function);
          }
        };
      IterableExtensions.<RCContractItemPromisedService>forEach(_promisedServices, _function_2);
    }
    product._deliver(enterprise);
  }
  
  public void cancelTransferPhysicalPruduct(final RCIdentifiablePhysicalProductEntry product) {
    RCLogicProduct _logicProduct = product.getLogicProduct();
    RCEnterprise _enterprise = product.getEnterprise();RCUnregisterIdentifiablePhysicalPruductEvent rCUnregisterIdentifiablePhysicalPruductEvent=RCUnregisterIdentifiablePhysicalPruductEventImpl.create(_logicProduct,_enterprise,getObjectFactory());
    final Procedure1<RCUnregisterIdentifiablePhysicalPruductEvent> _function = new Procedure1<RCUnregisterIdentifiablePhysicalPruductEvent>() {
        public void apply(final RCUnregisterIdentifiablePhysicalPruductEvent it) {
          Date _day = DateUtil.today();
          it.setDate(_day);
          User _currentUser = RCIdentifiablePhysicalProductEntryDAOImpl.this.systemUserService.getCurrentUser();
          it.setOperator(_currentUser);
        }
      };
    ObjectExtensions.<RCUnregisterIdentifiablePhysicalPruductEvent>operator_doubleArrow(rCUnregisterIdentifiablePhysicalPruductEvent, _function);
    RCEnterprise _hostEnterprise = this.organizationService.getHostEnterprise();
    product.setEnterprise(_hostEnterprise);
    RCLogicProduct _logicProduct_1 = product.getLogicProduct();
    RCEnterprise _hostEnterprise_1 = this.organizationService.getHostEnterprise();RCRegisterIdentifiablePhysicalPruductEvent rCRegisterIdentifiablePhysicalPruductEvent=RCRegisterIdentifiablePhysicalPruductEventImpl.create(_logicProduct_1,_hostEnterprise_1,getObjectFactory());
    final Procedure1<RCRegisterIdentifiablePhysicalPruductEvent> _function_1 = new Procedure1<RCRegisterIdentifiablePhysicalPruductEvent>() {
        public void apply(final RCRegisterIdentifiablePhysicalPruductEvent it) {
          Date _day = DateUtil.today();
          it.setDate(_day);
          User _currentUser = RCIdentifiablePhysicalProductEntryDAOImpl.this.systemUserService.getCurrentUser();
          it.setOperator(_currentUser);
        }
      };
    ObjectExtensions.<RCRegisterIdentifiablePhysicalPruductEvent>operator_doubleArrow(rCRegisterIdentifiablePhysicalPruductEvent, _function_1);
    product._return();
  }
  
  public RCIdentifiablePhysicalProductEntry registPartPhysicalProduct(final String sid, final String parentSid) {
    RCIdentifiablePhysicalProductEntry _xblockexpression = null;
    {
      boolean _notEquals = (!Objects.equal(sid, null));
      Validates.Assert(_notEquals, "\u8BBE\u5907\u5E8F\u5217\u53F7\u4E0D\u80FD\u4E3A\u7A7A");
      final RCIdentifiablePhysicalProductEntry parent = this.findProductBySid(parentSid);
      boolean _notEquals_1 = (!Objects.equal(parent, null));
      Validates.Assert(_notEquals_1, "\u7236\u8BBE\u5907\u4E0D\u5B58\u5728");
      RCLogicProduct _logicProduct = parent.getLogicProduct();
      String _projectid = _logicProduct.getProjectid();
      RCEnterprise _enterprise = parent.getEnterprise();
      RCIdentifiablePhysicalProductEntry __registerPhysicalProduct = this._registerPhysicalProduct(_projectid, _enterprise, sid, Integer.valueOf(1));
      final Procedure1<RCIdentifiablePhysicalProductEntry> _function = new Procedure1<RCIdentifiablePhysicalProductEntry>() {
          public void apply(final RCIdentifiablePhysicalProductEntry it) {
            it._import();
          }
        };
      RCIdentifiablePhysicalProductEntry _doubleArrow = ObjectExtensions.<RCIdentifiablePhysicalProductEntry>operator_doubleArrow(__registerPhysicalProduct, _function);
      _xblockexpression = (_doubleArrow);
    }
    return _xblockexpression;
  }
  
  public RCIdentifiablePhysicalProductEntry importPhysicalProduct(final String projectid, final RCEnterprise enterprise, final String sid) {
    RCIdentifiablePhysicalProductEntry _xblockexpression = null;
    {
      final RCIdentifiablePhysicalProductEntry result = this._registerPhysicalProduct(projectid, enterprise, sid, Integer.valueOf(1));
      result._import();
      _xblockexpression = (result);
    }
    return _xblockexpression;
  }
  
  /**
   * 产品入库，登记产品并将其入库至云多的库存
   * purchaseItem 为对应的合同清单的内容，需要追踪承诺服务信息
   */
  public RCIdentifiablePhysicalProductEntry inStockPhysicalProduct(final String sid, final RCPurchaseOrderItem orderItem, final RCBudgetContractProductItem contractItem, final Integer count) {
    RCIdentifiablePhysicalProductEntry _xblockexpression = null;
    {
      RCPurchaseOrder _purchaseOrder = orderItem.getPurchaseOrder();
      RCBudget _budget = _purchaseOrder.getBudget();
      RCCostBreakDown _cbd = _budget.getCbd();
      final RCProject project = _cbd.getProject();
      String _code = project.getCode();
      RCEnterprise _hostEnterprise = this.organizationService.getHostEnterprise();
      RCIdentifiablePhysicalProductEntry __registerPhysicalProduct = this._registerPhysicalProduct(_code, _hostEnterprise, sid, count);
      final Procedure1<RCIdentifiablePhysicalProductEntry> _function = new Procedure1<RCIdentifiablePhysicalProductEntry>() {
          public void apply(final RCIdentifiablePhysicalProductEntry p) {
            RCProductSpecification _productSpec = orderItem.getProductSpec();
            p.setType(_productSpec);
            RCPurchaseOrder _purchaseOrder = orderItem.getPurchaseOrder();
            RCSupplier _supplier = _purchaseOrder.getSupplier();
            p.setSupplier(_supplier);RCIdentifiablePhysicalProductInStockEvent rCIdentifiablePhysicalProductInStockEvent=RCIdentifiablePhysicalProductInStockEventImpl.create(getObjectFactory());
            final Procedure1<RCIdentifiablePhysicalProductInStockEvent> _function = new Procedure1<RCIdentifiablePhysicalProductInStockEvent>() {
                public void apply(final RCIdentifiablePhysicalProductInStockEvent it) {
                  it.setProduct(p);
                  Date _day = DateUtil.today();
                  it.setDate(_day);
                  it.setOrderItem(orderItem);
                  it.setContractItem(contractItem);
                  it.setQuantity(count);
                }
              };
            ObjectExtensions.<RCIdentifiablePhysicalProductInStockEvent>operator_doubleArrow(rCIdentifiablePhysicalProductInStockEvent, _function);
          }
        };
      final RCIdentifiablePhysicalProductEntry result = ObjectExtensions.<RCIdentifiablePhysicalProductEntry>operator_doubleArrow(__registerPhysicalProduct, _function);
      result._inStock(orderItem);
      _xblockexpression = (result);
    }
    return _xblockexpression;
  }
  
  public void cancelInStockPhysicalProduct(final RCIdentifiablePhysicalProductEntry product) {
    IGenericQuery<RCProductServiceTracer> query=getObjectFactory().createGenericQuery(RCProductServiceTracer.class,"select e2 from com.shrct.businessprocess.product.impl.RCProductServiceTracerImpl as e2   where ((e2.product) = (:product)) and  e2.active = 1      ").setParameter("product",product);
    final Collection<RCProductServiceTracer> serviceTracers = query.list();
    final Procedure1<RCProductServiceTracer> _function = new Procedure1<RCProductServiceTracer>() {
        public void apply(final RCProductServiceTracer it) {getObjectFactory().delete(it);
          
        }
      };
    IterableExtensions.<RCProductServiceTracer>forEach(serviceTracers, _function);
    IGenericQuery<RCIdentifiableProductInStockEvent> query_1=getObjectFactory().createGenericQuery(RCIdentifiableProductInStockEvent.class,"select e3 from com.shrct.businessprocess.purchase.impl.RCIdentifiableProductInStockEventImpl as e3   where ((e3.product) = (:product)) and  e3.active = 1      ").setParameter("product",product);
    final RCIdentifiableProductInStockEvent stockEvent = query_1.uniqueResult();getObjectFactory().delete(stockEvent);
    
    final RCLogicProduct logicProduct = product.getLogicProduct();
    IGenericQuery<RCIdentifiablePhysicalProductPurchaseInfo> query_2=getObjectFactory().createGenericQuery(RCIdentifiablePhysicalProductPurchaseInfo.class,"select e4 from com.shrct.businessprocess.product.impl.RCIdentifiablePhysicalProductPurchaseInfoImpl as e4   where ((e4.product) = (:product)) and  e4.active = 1      ").setParameter("product",product);
    final RCIdentifiablePhysicalProductPurchaseInfo entry = query_2.uniqueResult();getObjectFactory().delete(entry);
    getObjectFactory().delete(logicProduct);
    getObjectFactory().delete(product);
    
    product._cancelInStock();
  }
  
  public RCIdentifiablePhysicalProductEntry findProductBySid(final String sid) {
    IGenericQuery<RCIdentifiablePhysicalProductEntry> query=getObjectFactory().createGenericQuery(RCIdentifiablePhysicalProductEntry.class,"select e from com.shrct.businessprocess.product.impl.RCIdentifiablePhysicalProductEntryImpl as e   where ((e.sid) = (:sid)) and  e.active = 1      ").setParameter("sid",sid);
    RCIdentifiablePhysicalProductEntry _uniqueResult = query.uniqueResult();
    return _uniqueResult;
  }
  
  public RCIdentifiablePhysicalProductEntry registerExternalProduct4Service(final String projectid, final RCEnterprise customer, final String sid, final RCProductSpecification productSpec) {
    RCIdentifiablePhysicalProductEntry __registerPhysicalProduct = this._registerPhysicalProduct(projectid, customer, sid, Integer.valueOf(1));
    final Procedure1<RCIdentifiablePhysicalProductEntry> _function = new Procedure1<RCIdentifiablePhysicalProductEntry>() {
        public void apply(final RCIdentifiablePhysicalProductEntry it) {
          it.setType(productSpec);
        }
      };
    RCIdentifiablePhysicalProductEntry _doubleArrow = ObjectExtensions.<RCIdentifiablePhysicalProductEntry>operator_doubleArrow(__registerPhysicalProduct, _function);
    return _doubleArrow;
  }
}
